//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: StorageCommandBuilderCollection.cs
//
//  Description: Provides a collection for the storage command builder.
// 
//--------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Chili.Opf3.Query;
using System.Collections.ObjectModel;

namespace Chili.Opf3.Storages
{
	/// <summary>
	/// This class holds a collection of classes that implement the 
	/// <see cref="IStorageCommandBuilder">IStorageCommandBuilder</see> interface. For 
	/// more information about the <see cref="IStorageCommandBuilder">IStorageCommandBuilder</see>
	/// classes look at the documentation of the interface.
	/// </summary>
	public sealed class StorageCommandBuilderCollection : Collection<IStorageCommandBuilder>
	{
		private IStorage _storage;

		/// <summary>
		/// Creates a new instance of the 
		/// <see cref="StorageCommandBuilderCollection">StorageCommandBuilderCollection Class</see>.
		/// </summary>
		/// <param name="storage">Specifies the storage associated with this collection.</param>
		internal StorageCommandBuilderCollection(IStorage storage)
		{
			if (storage == null)
				throw new ArgumentNullException("storage");
			_storage = storage;
		}

		/// <summary>
		/// Returns the <see cref="IStorageCommandBuilder">IStorageCommandBuilder</see> that is able to convert
		/// the given query.
		/// </summary>
		/// <param name="query">The query that should be transformed to a storage dependent query.</param>
		/// <returns>A <see cref="CompiledQuery">CompiledQuery</see> instance that represents the storage dependent query.</returns>
		/// <exception cref="NotSupportedException">If no class that implements the <see cref="IStorageCommandBuilder">IStorageCommandBuilder</see>
		/// interface and is registered with the storage can handle the given query.</exception>
		public IStorageCommandBuilder GetStorageCommandBuilder(IQuery query)
		{
			foreach (IStorageCommandBuilder c in this)
			{
				if (c.IsSupported(_storage, query))
					return c;
			}

			// Throw an exception if the query type is not supported by the storage.
			throw new NotSupportedException(string.Format("Storage doesn't support the given type of query. Query type: {0}", query.GetType()));
		}
	}
}
